package org.wu.framework.easy.excel.util;

import org.springframework.util.ObjectUtils;
import org.wu.framework.core.NormalUsedString;
import org.wu.framework.easy.excel.endpoint.EasyExcelFieldPoint;
import org.wu.framework.easy.excel.endpoint.ExportFieldCommand;

import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 *
 * 使用 声明自定义表头数据
 * DynamicEasyExcelContextHolder.pushOnlyExportField(easyExcelFiledPointList);
 */
public class ExportFieldCommandUtils {

    /**
     * 将自定义表头转换成 EasyExcelFieldPoint
     *
     * @param exportFieldCommandList 导出字段
     * @return List<EasyExcelFieldPoint>
     */
    public static  List<EasyExcelFieldPoint> exportFieldCommandList2EasyExcelFiledPointList(List<ExportFieldCommand> exportFieldCommandList) {
        return exportFieldCommandList2EasyExcelFiledPointList(exportFieldCommandList, new ConcurrentHashMap<>());
    }

    /**
     * 将自定义表头转换成 EasyExcelFieldPoint
     *
     * @param exportFieldCommandList 导出字段
     * @param cacheNameFieldMap      缓存字段
     * @return List<EasyExcelFieldPoint>
     */
    public static List<EasyExcelFieldPoint> exportFieldCommandList2EasyExcelFiledPointList(List<ExportFieldCommand> exportFieldCommandList,
                                                                                           ConcurrentHashMap<String, EasyExcelFieldPoint> cacheNameFieldMap) {
        List<ExportFieldCommand> fieldCommandList = exportFieldCommandList.stream()
                .sorted(Comparator.comparing(ExportFieldCommand::getSerialNumber)).collect(Collectors.toList());
        // 字段排序
        for (int i = 0; i < fieldCommandList.size(); i++) {
            fieldCommandList.get(i).setCurrentColumnIndex(i);
        }
        return recursionField(fieldCommandList, cacheNameFieldMap, NormalUsedString.EMPTY);
    }

    /**
     * 递归字段为导出数据字段
     *
     * @param exportFieldCommandList 导出字段
     * @param cacheNameFieldMap      缓存字段
     * @param prefix                 如果是对象或者是集合对应的字段前缀
     * @return List<EasyExcelFieldPoint>
     */
    public static List<EasyExcelFieldPoint> recursionField(List<ExportFieldCommand> exportFieldCommandList,
                                                           ConcurrentHashMap<String, EasyExcelFieldPoint> cacheNameFieldMap,
                                                           String prefix) {


        return exportFieldCommandList
                .stream()
                .filter(exportFieldCommand -> ObjectUtils.isEmpty(prefix) || exportFieldCommand.getName().startsWith(prefix.replaceAll("\\\\", NormalUsedString.EMPTY)))

                .sorted(Comparator.comparing(ExportFieldCommand::getSerialNumber))
                .map(exportFieldCommand -> {
                    String name = exportFieldCommand.getName();
                    Integer currentColumnIndex = exportFieldCommand.getCurrentColumnIndex();

                    String columnTitleName = exportFieldCommand.getColumnTitleName();
                    Integer serialNumber = exportFieldCommand.getSerialNumber();
                    EasyExcelFieldPoint easyExcelFieldPoint = new EasyExcelFieldPoint();
                    // 递归处理
                    if (!ObjectUtils.isEmpty(prefix)) {
                        name = name.replaceFirst(prefix, NormalUsedString.EMPTY);
                    }

                    // 判断数组或者对象
                    int collectionFiledFirstIndexOf = name.indexOf(NormalUsedString.DOT + NormalUsedString.DOLLAR);
                    int beanFiledFirstIndexOf = name.indexOf(NormalUsedString.DOT);
                    if (beanFiledFirstIndexOf == -1) {
                        // 常规字段
                        easyExcelFieldPoint.setName(columnTitleName);
                        easyExcelFieldPoint.setSerialNumber(serialNumber);
                        easyExcelFieldPoint.setFieldName(name);
                        easyExcelFieldPoint.setCurrentColumnIndex(currentColumnIndex);
                    } else if (collectionFiledFirstIndexOf <= beanFiledFirstIndexOf) {
                        // 集合
                        // 对象集合字段
                        String[] split = name.split("\\.");
                        String beanName = split[0];
                        String cacheKey = ObjectUtils.isEmpty(prefix) ? beanName + NormalUsedString.DOT + NormalUsedString.BACK_SLASH + NormalUsedString.DOLLAR :
                                prefix + beanName + NormalUsedString.DOT + NormalUsedString.BACK_SLASH + NormalUsedString.DOLLAR;
                        if (cacheNameFieldMap.containsKey(cacheKey)) {
                            return null;
                        }
                        EasyExcelFieldPoint orDefault = cacheNameFieldMap.getOrDefault(cacheKey, easyExcelFieldPoint);
                        orDefault.setCollectionFiled(true);
                        orDefault.setName(beanName);
                        orDefault.setFieldName(beanName);
                        orDefault.setSerialNumber(serialNumber);
                        List<EasyExcelFieldPoint> beanFieldEasyExcelFieldPointList = recursionField(exportFieldCommandList, cacheNameFieldMap, cacheKey);
                        List<EasyExcelFieldPoint> excelBeanFiledPointList = orDefault.getExcelBeanFiledPointList();
                        if (ObjectUtils.isEmpty(excelBeanFiledPointList)) {
                            orDefault.setExcelBeanFiledPointList(beanFieldEasyExcelFieldPointList);
                        } else {
                            orDefault.getExcelBeanFiledPointList().addAll(beanFieldEasyExcelFieldPointList);
                        }
                        orDefault.setCurrentColumnIndex(currentColumnIndex);
                        cacheNameFieldMap.put(cacheKey, orDefault);
                    } else {
                        // 对象
                        // 对象字段
                        // 这是一个对象
                        if (!ObjectUtils.isEmpty(prefix)) {
                            name = name.replaceFirst(prefix + NormalUsedString.DOT, NormalUsedString.EMPTY);
                        }

                        String[] split = name.split("\\.");
                        String beanName = split[0];
                        String cacheKey = ObjectUtils.isEmpty(prefix) ? beanName + NormalUsedString.DOT : prefix + beanName + NormalUsedString.DOT;

                        if (cacheNameFieldMap.containsKey(cacheKey)) {
                            return null;
                        }
                        EasyExcelFieldPoint orDefault = cacheNameFieldMap.getOrDefault(cacheKey, easyExcelFieldPoint);
                        orDefault.setName(beanName);
                        orDefault.setFieldName(beanName);
                        orDefault.setBeanFiled(true);
                        orDefault.setSerialNumber(serialNumber);
                        List<EasyExcelFieldPoint> beanFieldEasyExcelFieldPointList = recursionField(exportFieldCommandList, cacheNameFieldMap, cacheKey);

                        List<EasyExcelFieldPoint> excelBeanFiledPointList = orDefault.getExcelBeanFiledPointList();
                        if (ObjectUtils.isEmpty(excelBeanFiledPointList)) {
                            orDefault.setExcelBeanFiledPointList(beanFieldEasyExcelFieldPointList);
                        } else {
                            orDefault.getExcelBeanFiledPointList().addAll(beanFieldEasyExcelFieldPointList);
                        }
                        orDefault.setCurrentColumnIndex(currentColumnIndex);
                        cacheNameFieldMap.put(cacheKey, orDefault);
                    }
                    // 设置样式

                    return easyExcelFieldPoint;
                }).filter(Objects::nonNull).collect(Collectors.toList());
    }
}
